home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Online / opennap / timer.c < prev    next >
C/C++ Source or Header  |  2001-06-08  |  3KB  |  138 lines

  1. /* Copyright (C) 2000 edwards@bitchx.dimension6.com
  2.    This is free software distributed under the terms of the
  3.    GNU Public License.  See the file COPYING for details.
  4.  
  5.    Modified by drscholl@users.sourceforge.net 2/29/2000.
  6.  
  7.    $Id: timer.c,v 1.9 2001/02/13 08:41:15 drscholl Exp $ */
  8.  
  9. #include <time.h>
  10. #include <stdlib.h>
  11. #include "opennap.h"
  12. #include "debug.h"
  13.  
  14. typedef struct _timerstruct
  15. {
  16.     struct _timerstruct *next;
  17.     timer_cb_t func;
  18.     void   *arg;
  19.     time_t  next_time;
  20.     time_t  interval;
  21.     int     events;
  22.     unsigned int refnum;
  23. }
  24. TIMER;
  25.  
  26. static TIMER *Pending_Timers = NULL;
  27. static unsigned int TimerRef = 0;
  28.  
  29. static void
  30. schedule_timer (TIMER * ntimer)
  31. {
  32.     TIMER **slot;
  33.  
  34.     if (!ntimer->events)
  35.     return;
  36.  
  37.     /* we've created it, now put it in order */
  38.     for (slot = &Pending_Timers; *slot; slot = &(*slot)->next)
  39.     {
  40.     if (ntimer->next_time < (*slot)->next_time)
  41.         break;
  42.     }
  43.     ntimer->next = *slot;
  44.     *slot = ntimer;
  45. }
  46.  
  47. /* returns the refnum */
  48. int
  49. add_timer (int interval, int events, timer_cb_t func, void *arg)
  50. {
  51.     TIMER  *new;
  52.  
  53.     if (!events)
  54.     return -1;
  55.     new = CALLOC (1, sizeof (TIMER));
  56.     if (!new)
  57.     {
  58.     OUTOFMEMORY ("add_timer");
  59.     return -1;
  60.     }
  61.     new->next_time = global.current_time + interval;
  62.     new->interval = interval;
  63.     new->func = func;
  64.     new->arg = arg;
  65.     new->events = events;
  66.     new->refnum = TimerRef++;
  67.     schedule_timer (new);
  68.  
  69.     return new->refnum;
  70. }
  71.  
  72. void
  73. exec_timers (time_t now)
  74. {
  75.     TIMER  *current;
  76.  
  77.     while (Pending_Timers && Pending_Timers->next_time <= now)
  78.     {
  79.     current = Pending_Timers;
  80.     Pending_Timers = current->next;
  81.     (*current->func) (current->arg);
  82.     switch (current->events)
  83.     {
  84.     case 0:
  85.         FREE (current);
  86.         break;
  87.     default:
  88.         current->events--;
  89.     case -1:
  90.         /* reschedule */
  91.         current->next_time = global.current_time + current->interval;
  92.         schedule_timer (current);
  93.         break;
  94.     }
  95.     }
  96. }
  97.  
  98. /* returns the time offset at which the next pending event is scheduled */
  99. time_t next_timer (void)
  100. {
  101.     if (Pending_Timers)
  102.     {
  103.     if (Pending_Timers->next_time < global.current_time)
  104.         return 0;        /* now! */
  105.     return (Pending_Timers->next_time - global.current_time);
  106.     }
  107.     return -1;
  108. }
  109.  
  110. void
  111. free_timers (void)
  112. {
  113.     TIMER  *ptr;
  114.  
  115.     while (Pending_Timers)
  116.     {
  117.     ptr = Pending_Timers;
  118.     Pending_Timers = Pending_Timers->next;
  119.     FREE (ptr);
  120.     }
  121. }
  122.  
  123. /* change the interval at which a timer occurs.  note that this does not
  124.  * reschedule a currently pending event, and only affect subsequent calls
  125.  */
  126. void
  127. timer_set_interval (unsigned int refnum, int interval)
  128. {
  129.     TIMER  *t = Pending_Timers;
  130.  
  131.     for (; t; t = t->next)
  132.     if (t->refnum == refnum)
  133.     {
  134.         t->interval = interval;
  135.         break;
  136.     }
  137. }
  138.